home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / motif / ostencil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.0 KB  |  333 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*----------------------------------------------------------------------------
  18.  *
  19.  * ostencil.c : openGL (motif) example showing how to use stencils
  20.  *
  21.  * Author : Yusuf Attarwala
  22.  *          SGI - Applications
  23.  * Date   : Mar 93
  24.  *
  25.  *    note : the main intent of this program is to demo the stencil
  26.  *           plane functionality, hence the rendering is kept
  27.  *           simple (wireframe).
  28.  *
  29.  *    press  left   button for animation
  30.  *    press  middle button to turn OFF stenciling
  31.  *    press  right  button to turn ON  stenciling
  32.  *
  33.  *---------------------------------------------------------------------------*/
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37.  
  38. #include <Xm/Xm.h> 
  39. #include <Xm/Frame.h>               /* for frame widgets */
  40. #include <Xm/Form.h>               /* for frame widgets */
  41. #include <X11/keysym.h>             /* keyboard translations */
  42. #include <X11/StringDefs.h>
  43.  
  44. #include <GL/gl.h>                  /* gl includes */
  45. #include <GL/glu.h>                 /* utility library includes */
  46. #include <GL/GLwMDrawA.h>           /* include for the drawing area widget */
  47.  
  48. static int stencilOn = 1;
  49.  
  50. /* function declarations */
  51.  
  52. void 
  53.     createToplevel(void),
  54.     drawScene(void),
  55.     setMatrix(void),
  56.     setEtchingArea(void),
  57.     initLightAndMaterial(void),
  58.     animation(void),
  59.     exposeCB(Widget,XtPointer,XtPointer),
  60.     resizeCB(Widget,XtPointer,XtPointer),
  61.     initCB(Widget,XtPointer,XtPointer),
  62.     inputCB(Widget,XtPointer,XtPointer);
  63.  
  64.  
  65. /* global variables */
  66.             
  67. Display       *display;             /* current display */
  68. XtAppContext  appContext;           /* X application context */
  69. float         ax,ay,az;             /* angles for animation */
  70. GLUquadricObj *quadObj;             /* used in drawscene */
  71.  
  72. Widget        toplevel,       /* toplevel shell */
  73.               glw;            /* current widget */
  74.              
  75. GLXContext    glxc;           /* current glx context */
  76.  
  77. Arg args[20];
  78. int acnt;
  79.  
  80. void 
  81. main(int argc, char** argv)
  82. {
  83.     XtToolkitInitialize();
  84.     appContext = XtCreateApplicationContext();
  85.     display    = XtOpenDisplay(appContext, NULL, "Ostencil","ostencil",NULL,0,
  86.                               &argc,argv);
  87.     if (!display) {
  88.         printf("%s : Unable to open display\n",argv[0]);
  89.         exit(0);
  90.     }
  91.  
  92.     printf("\n---------------------------------------------\n");
  93.     printf("OpenGL stencil example \n\n");
  94.     printf("Press:  left   button for animation\n\
  95.         middle button to turn OFF stenciling\n\
  96.         right  button to turn ON  stenciling (default)\n");
  97.  
  98.     quadObj = gluNewQuadric ();   /* this will be used in drawScene */
  99.     createToplevel();             /* create widget hierarchy */
  100.     XtAppMainLoop(appContext);    /* loop forever */
  101. }
  102.  
  103.  
  104. void
  105. createToplevel(void)
  106. {
  107.     Widget frame;
  108.  
  109.     acnt = 0;
  110.     XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
  111.     XtSetArg(args[acnt],XmNminWidth,  300);acnt++;
  112.     XtSetArg(args[acnt],XmNminAspectX,  1);acnt++;
  113.     XtSetArg(args[acnt],XmNminAspectY,  1);acnt++;
  114.     XtSetArg(args[acnt],XmNmaxAspectX,  1);acnt++;
  115.     XtSetArg(args[acnt],XmNmaxAspectY,  1);acnt++;
  116.     toplevel  = XtAppCreateShell("openGL stencil","ostencil",
  117.                                   applicationShellWidgetClass,
  118.                                   display,args,acnt);
  119.  
  120.     /* create a frame to hold glx widget */
  121.     frame   = XtVaCreateManagedWidget("frame", 
  122.                   xmFrameWidgetClass, toplevel, 
  123.                   NULL);
  124.  
  125.     /* create a double buffer widget, in rgb mode and manage it */
  126.     acnt = 0;
  127.     XtSetArg(args[acnt], GLwNrgba,               TRUE); acnt++;
  128.     XtSetArg(args[acnt], GLwNdoublebuffer,       TRUE); acnt++;
  129.     XtSetArg(args[acnt], GLwNstencilSize,        1); acnt++;
  130.     XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
  131.     glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
  132.     XtManageChild(glw);
  133.  
  134.     /* register callbacks */
  135.     XtAddCallback(glw, GLwNginitCallback,  initCB,   NULL);
  136.  
  137.     /* realize widget hierarchy */
  138.     XtRealizeWidget(toplevel);
  139.  
  140.     /*
  141.     initLightAndMaterial();
  142.     */
  143.  
  144.     /* additional callbacks */
  145.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
  146.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
  147.     XtAddCallback(glw, GLwNinputCallback,  inputCB,  NULL);
  148.  
  149. }
  150.  
  151. static float p0[] = {-5.0,-5.0,0.0};
  152. static float p1[] = {5.0,-5.0,0.0};
  153. static float p2[] = {5.0,5.0,0.0};
  154. static float p3[] = {-5.0,5.0,0.0};
  155.  
  156. void
  157. setEtchingArea()
  158. {
  159.     /* create a rectangle in the center where the stencil
  160.        bits are set */
  161.  
  162.     glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  163.     glClearStencil(0);
  164.     glClear(GL_STENCIL_BUFFER_BIT);
  165.  
  166.     glEnable(GL_STENCIL_TEST);
  167.     glStencilFunc(GL_ALWAYS,1,1);
  168.     glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
  169.     glBegin(GL_POLYGON);
  170.         glVertex3fv(p0);
  171.         glVertex3fv(p1);
  172.         glVertex3fv(p2);
  173.         glVertex3fv(p3);
  174.     glEnd();
  175.     
  176.     glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  177.     glDisable(GL_STENCIL_TEST);
  178. }
  179.  
  180. void
  181. drawScene(void)
  182. {
  183.  
  184.     glClearColor(0.3, 0.3, 0.3, 0.0);
  185.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  186.  
  187.     /* draw the etched area in a different color for visual clue */
  188.     /* note that the stencil test is disabled at this point */
  189.  
  190.     glColor3f (0.0, 0.0, 0.0);
  191.     glBegin(GL_POLYGON);
  192.         glVertex3fv(p0);
  193.         glVertex3fv(p1);
  194.         glVertex3fv(p2);
  195.         glVertex3fv(p3);
  196.     glEnd();
  197.  
  198.     if (stencilOn) glEnable(GL_STENCIL_TEST);
  199.     glPushMatrix();
  200.     gluQuadricDrawStyle (quadObj, GLU_LINE);
  201.  
  202.     glRotatef (ax,1.0,0.0,0.0);
  203.     glRotatef (-ay,0.0, 1.0, 0.0);
  204.  
  205.     /* draw a cone where the stencil is not set to 1 */
  206.     glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  207.     glStencilFunc(GL_NOTEQUAL,1,1);
  208.     glColor3f (1.0, 1.0, 0.0);
  209.     gluCylinder (quadObj, 2.0,5.0,10.0,20,8);  /* draw a cone */
  210.  
  211.     /* draw a cone (in different color) where the stencil is set to 1 */
  212.     glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  213.     glStencilFunc(GL_EQUAL,1,1);
  214.     glColor3f (0.0, 1.0, 1.0);
  215.     gluCylinder (quadObj, 2.0,5.0,10.0,20,8);  /* draw a cone */
  216.  
  217.     glPopMatrix();
  218.     if (stencilOn) glDisable(GL_STENCIL_TEST);
  219.  
  220.     glFlush();
  221.     glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
  222.  
  223. }
  224.  
  225. void
  226. setMatrix(void)
  227. {
  228.     glMatrixMode(GL_PROJECTION);
  229.     glLoadIdentity();
  230.     glOrtho(-12.0,12.0,-12.0,12.0,-12.0,12.0);
  231.     glMatrixMode(GL_MODELVIEW);
  232.     glLoadIdentity();
  233. }
  234.  
  235. void
  236. animation(void)
  237. {
  238.     register int i;
  239.     /* animate the cone */
  240.  
  241.     for (i=0;i<60;i++) {
  242.         ax += 5.0;
  243.         ay -= 2.0;
  244.         az += 5.0;
  245.         if (ax >= 360)  ax = 0.0;
  246.         if (ay <= -360) ay = 0.0;
  247.         if (az >= 360)  az = 0.0;
  248.         drawScene();
  249.     }
  250. }
  251.  
  252. void 
  253. inputCB(Widget w, XtPointer client_data, XtPointer call)
  254. {
  255.     char            string[31];
  256.     XComposeStatus  composeStatus;
  257.     KeySym keysym;
  258.     GLwDrawingAreaCallbackStruct *call_data;
  259.  
  260.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  261.  
  262.     switch(call_data->event->type) {
  263.     case ButtonPress:
  264.         switch (call_data->event->xbutton.button) {
  265.         case Button1:
  266.         animation();
  267.             break;
  268.         case Button2 :
  269.         stencilOn = 0;
  270.         drawScene();
  271.             break;
  272.         case Button3 :
  273.         stencilOn = 1;
  274.         drawScene();
  275.             break;
  276.         }
  277.         break;
  278.     case KeyPress :
  279.         XLookupString((XKeyEvent *)call_data->event,string,
  280.                       30,&keysym,&composeStatus);
  281.         switch(keysym) {
  282.         case XK_Escape :
  283.             exit(0);
  284.             break;
  285.         }
  286.     break;
  287.     default:
  288.         break;
  289.     }
  290. }
  291.  
  292. void 
  293. resizeCB(Widget w, XtPointer client_data, XtPointer call)
  294. {
  295.     GLwDrawingAreaCallbackStruct *call_data;
  296.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  297.  
  298.     GLwDrawingAreaMakeCurrent(w, glxc);
  299.     glViewport(0, 0, call_data->width, call_data->height);
  300.     setMatrix();
  301.  
  302.     setEtchingArea();    /* using stencils */
  303.     drawScene();
  304. }
  305.  
  306. void 
  307. exposeCB(Widget w, XtPointer client_data, XtPointer call)
  308. {
  309.     GLwDrawingAreaCallbackStruct *call_data;
  310.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  311.  
  312.  
  313.     GLwDrawingAreaMakeCurrent(w, glxc);
  314.     glViewport(0, 0, call_data->width, call_data->height);
  315.     drawScene();
  316. }
  317.  
  318. void
  319. initCB(Widget w, XtPointer client_data, XtPointer call)
  320. {
  321.     XVisualInfo *vi;
  322.  
  323.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  324.     XtGetValues(w, args, 1);
  325.  
  326.     glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
  327.  
  328.     ax = 10.0;
  329.     ay = -10.0;
  330.     az = 0.0;
  331. }
  332.  
  333.